package com.dinzeer.sjapadder.sa;

import com.dinzeer.legendreliclib.lib.util.WaitingTick;
import com.dinzeer.legendreliclib.lib.util.check.CheckEntity;
import com.dinzeer.legendreliclib.lib.util.slashblade.SlashBladeUtil;
import mods.flammpfeil.slashblade.SlashBlade;
import mods.flammpfeil.slashblade.capability.concentrationrank.ConcentrationRankCapabilityProvider;
import mods.flammpfeil.slashblade.entity.EntityJudgementCut;
import mods.flammpfeil.slashblade.entity.EntitySlashEffect;
import mods.flammpfeil.slashblade.util.KnockBacks;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;

import static com.dinzeer.sjapadder.Config.fireDanceCircleSlashDamage;
import static com.dinzeer.sjapadder.Config.fireDanceJudgementCutDamage;

public class FireDance {

    public static void doBurningDance(LivingEntity entityIn) {
        LivingEntity target = CheckEntity.getPointedLivingEntity(entityIn, 50.0F);
        if (target == null) return;
        
        // 第一阶段攻击
        doCircleSlash(entityIn, -30.0F, 180.0F, target);
        doCircleSlash(entityIn, -30.0F, 90.0F, target);
        doCircleSlash(entityIn, -30.0F, 0.0F, target);
        doCircleSlash(entityIn, -30.0F, -90.0F, target);
        
        // 延迟执行第二阶段攻击
        WaitingTick.schedule(3, () -> {
            doCircleSlash(entityIn, 30.0F, 180.0F, target);
            doCircleSlash(entityIn, 30.0F, 90.0F, target);
            doCircleSlash(entityIn, 30.0F, 0.0F, target);
            doCircleSlash(entityIn, 30.0F, -90.0F, target);
        });
        
        // 延迟执行第三阶段攻击
        WaitingTick.schedule(5, () -> {
            doCircleSlash(entityIn, 90.0F, 180.0F, target);
            doCircleSlash(entityIn, 90.0F, 90.0F, target);
            doCircleSlash(entityIn, 90.0F, 0.0F, target);
            doCircleSlash(entityIn, 90.0F, -90.0F, target);
        });
        
        // 延迟执行第四阶段攻击
        WaitingTick.schedule(8, () -> {
            doCircleSlash(entityIn, -45.0F, 180.0F, target);
            doCircleSlash(entityIn, -45.0F, 90.0F, target);
            doCircleSlash(entityIn, -45.0F, 0.0F, target);
            doCircleSlash(entityIn, -45.0F, -90.0F, target);
        });

        // 对目标周围3格内的生物造成16次伤害并点燃
        for (int i = 0; i < 16; i++) {
            target.level().getEntitiesOfClass(LivingEntity.class,
                    target.getBoundingBox().inflate(3F)).forEach(e -> {
                if (e != entityIn) {
                    e.invulnerableTime = 0;
                    e.setSecondsOnFire(10);
                    e.hurt(entityIn.damageSources().mobAttack(entityIn), 
                          SlashBladeUtil.getBaseAttackModifier(entityIn.getMainHandItem()));
                }
            });
        }

        // 创建并添加最终审判斩
        EntityJudgementCut judgementCut = new EntityJudgementCut(SlashBlade.RegistryEvents.JudgementCut, target.level());
        judgementCut.setPos(target.getX(),
                target.getY() + target.getEyeHeight() * 0.75F+1
                , target.getZ());
        judgementCut.setIsCritical(true);
        judgementCut.setDamage(fireDanceJudgementCutDamage);
        judgementCut.setColor(16711680);
        judgementCut.setOwner(entityIn);
        target.level().addFreshEntity(judgementCut);
    }

    private static void spawnParticle(ParticleOptions type, LivingEntity player, int num, double rate) {
        Level world = player.level();
        RandomSource random = player.getRandom();

        for(int i = 0; i < num && !player.level().isClientSide(); ++i) {
            double xDist = (double)(random.nextFloat() * 2.0F - 1.0F);
            double yDist = (double)(random.nextFloat() * 2.0F - 1.0F);
            double zDist = (double)(random.nextFloat() * 2.0F - 1.0F);
            if (!(xDist * xDist + yDist * yDist + zDist * zDist > (double)1.0F)) {
                double x = player.getX() + ((random.nextDouble() * (double)2.0F - (double)1.0F) * (double)player.getBbWidth() - random.nextGaussian() * 0.02 * (double)10.0F) * rate;
                double y = player.getY();
                double z = player.getZ() + ((random.nextDouble() * (double)2.0F - (double)1.0F) * (double)player.getBbWidth() - random.nextGaussian() * 0.02 * (double)10.0F) * rate;
                ((ServerLevel)world).sendParticles(type, x, y, z, 0, xDist, yDist + 0.2, zDist, (double)1.0F);
            }
        }

    }

    public static void doCircleSlash(LivingEntity living, float roll, float yRot, LivingEntity target) {
        if (!living.level().isClientSide()) {
            spawnParticle(ParticleTypes.SMALL_FLAME, living, 25, (double)2.0F);
            Vec3 pos = new Vec3(
                target.getX(),
                target.getY() + target.getEyeHeight() * 0.75F+1,
                target.getZ()
            );
            EntitySlashEffect jc = new EntitySlashEffect(SlashBlade.RegistryEvents.SlashEffect, living.level()) {
                public SoundEvent getSlashSound() {
                    return SoundEvents.EMPTY;
                }
            };
            jc.setPos(pos.x, pos.y, pos.z);
            jc.setOwner(living);
            jc.setRotationRoll(roll);
            jc.setYRot(target.getYRot() - 22.5F + yRot);
            jc.setXRot(0.0F);
            jc.setColor(16711680);
            jc.setMute(false);
            jc.setIsCritical(true);
            jc.setDamage(fireDanceCircleSlashDamage);
            jc.setKnockBack(KnockBacks.cancel);
            if (living != null) {
                living.getCapability(ConcentrationRankCapabilityProvider.RANK_POINT).ifPresent((rank) -> jc.setRank(rank.getRankLevel(living.level().getGameTime())));
            }

            living.level().addFreshEntity(jc);
        }
    }
}
